/**
 *  (c)
 * <p>
 *
 * <p>
 *
 */

package com.nn.smart.bus.controller;

import com.nn.smart.bus.commons.tools.constant.Constant;
import com.nn.smart.bus.commons.tools.exception.ErrorCode;
import com.nn.smart.bus.commons.tools.security.user.UserDetail;
import com.nn.smart.bus.commons.tools.utils.ConvertUtils;
import com.nn.smart.bus.commons.tools.utils.Result;
import com.nn.smart.bus.commons.tools.validator.AssertUtils;
import com.nn.smart.bus.commons.tools.validator.ValidatorUtils;
import com.nn.smart.bus.dto.AuthorizationDTO;
import com.nn.smart.bus.dto.LoginDTO;
import com.nn.smart.bus.dto.SysUserOpenIdFormDTO;
import com.nn.smart.bus.service.AuthService;
import com.nn.smart.bus.service.CaptchaService;
import com.nn.smart.bus.service.ResourceService;
import com.nn.smart.bus.common.token.dto.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;

/**
 * 授权管理
 *
 * @author nanning
 * @since 1.0.0
 */
@RestController
@Api(tags = "授权管理")
public class AuthController {
    @Autowired
    private AuthService authService;
    @Autowired
    private ResourceService resourceService;
    @Autowired
    private CaptchaService captchaService;

    @GetMapping("captcha")
    @ApiOperation(value = "验证码", produces = "application/octet-stream")
    @ApiImplicitParam(paramType = "query", dataType = "string", name = "uuid", required = true)
    public void captcha(HttpServletResponse response, String uuid) throws IOException {
        //uuid不能为空
        AssertUtils.isBlank(uuid, ErrorCode.IDENTIFIER_NOT_NULL);

        //生成图片验证码
        BufferedImage image = captchaService.create(uuid);

        response.setHeader("Cache-Control", "no-store, no-cache");
        response.setContentType("image/jpeg");
        ServletOutputStream out = response.getOutputStream();
        ImageIO.write(image, "jpg", out);
        out.close();
    }

    @PostMapping(value = "login")
    @ApiOperation(value = "登录")
    public Result<AuthorizationDTO> login(@RequestBody LoginDTO login) {
        //效验数据
        ValidatorUtils.validateEntity(login);

        //获取登录授权信息
        AuthorizationDTO authorization = authService.login(login);

        return new Result<AuthorizationDTO>().ok(authorization);
    }

    /**
     *
     * 工作端-获取token
     *
     * @params [tokenFormDto]
     * @return com.nn.smart.bus.commons.tools.utils.Result<com.nn.smart.bus.common.token.dto.WorkUserAuthorizationDTO>
     * @author nanning
     * @since 2019/11/19 20:46
     */
    @GetMapping(value = "getToken")
    public Result<WorkUserAuthorizationDTO> getToken(@RequestBody WorkUserTokenFormDTO tokenFormDto) {
        //效验数据
        ValidatorUtils.validateEntity(tokenFormDto);

        return authService.workLogin(tokenFormDto.getUsername(), null);
    }

    /**
     *
     * 工作端-用户登录
     *
     * @params [workUserLoginDto]
     * @return com.nn.smart.bus.commons.tools.utils.Result<com.nn.smart.bus.common.token.dto.WorkUserAuthorizationDTO>
     * @author nanning
     * @since 2019/11/19 20:21
     */
    @PostMapping(value = "workLogin")
    @ApiOperation(value = "登录")
    public Result<WorkUserAuthorizationDTO> workLogin(@RequestBody WorkUserLoginDTO workUserLoginDto) {
        //效验数据
        ValidatorUtils.validateEntity(workUserLoginDto);
        Result<WorkUserAuthorizationDTO> result = authService.workLogin(workUserLoginDto.getUsername(), workUserLoginDto.getPassword());
        if (result.success()) {
            // 解绑上一次登录账户并绑定当前账户
            SysUserOpenIdFormDTO sysUserOpenIdFormDto = ConvertUtils.sourceToTarget(workUserLoginDto, SysUserOpenIdFormDTO.class);
            authService.modifyOpenId(sysUserOpenIdFormDto);
        }

        return result;
    }

    @PostMapping(value = "logout")
    @ApiOperation(value = "退出")
    public Result logout(HttpServletRequest request) {
        String userId = request.getHeader(Constant.USER_KEY);

        authService.logout(Long.parseLong(userId));

        return new Result();
    }

    /**
     * 是否有资源访问权限
     *
     * @param token  token
     * @param url    资源URL
     * @param method 请求方式
     * @return 有访问权限，则返回用户信息
     */
    @PostMapping("resource")
    public Result<UserDetail> resource(@RequestParam(value = "token", required = false) String token,
                                       @RequestParam("url") String url, @RequestParam("method") String method) {
        UserDetail data = resourceService.resource(token, url, method);

        return new Result<UserDetail>().ok(data);
    }

    /**
     * 退出登录
     * @param userId
     * @Author nanning
     * @return
     */
    @GetMapping("logoutUser/{userId}")
    public Result logoutUser(@PathVariable("userId") String userId) {

        return authService.logoutUser(Long.parseLong(userId));
    }

    /**
     *
     * 数据端-用户凭证登录
     *
     * @params [workUserLoginDto]
     * @return com.nn.smart.bus.commons.tools.utils.Result<com.nn.smart.bus.common.token.dto.WorkUserAuthorizationDTO>
     * @author nanning
     * @since 2020/06/22 20:21
     */
    @PostMapping(value = "workScripLogin")
    public Result<WorkUserAuthorizationDTO> workScripLogin(@RequestBody WorkUserScripLoginDTO workUserLoginDto) {
        //效验数据
        ValidatorUtils.validateEntity(workUserLoginDto);
        Result<WorkUserAuthorizationScripDTO> result = authService.workScripLogin(workUserLoginDto.getScrip());
        if (result.success()) {
            workUserLoginDto.setUsername(result.getData().getUsername());
            // 解绑上一次登录账户并绑定当前账户
            SysUserOpenIdFormDTO sysUserOpenIdFormDto = ConvertUtils.sourceToTarget(workUserLoginDto, SysUserOpenIdFormDTO.class);
            authService.modifyOpenId(sysUserOpenIdFormDto);
        }

        return new Result<WorkUserAuthorizationDTO>().ok(result.getData().getWorkUserAuthorizationDTO());
    }
}
